package com.tianchi.lexiang.background;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;


import com.tianchi.lexiang.R;
import com.tianchi.lexiang.background.util.DatabaseEncryptionUtil;
import com.tianchi.lexiang.background.util.HddDataBaseVersion;
import com.tianchi.lexiang.background.util.InternetAddSongUtil;
import com.tianchi.lexiang.background.util.UDiskAddSongUtil;
import com.tianchi.lexiang.bean.LeXiangConstants;
import com.tianchi.lexiang.bean.Song;
import com.tianchi.lexiang.util.FtpUnit;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class InternetDownLoad extends Activity {
	
	private static final String TAG = "InternetDownLoad";
	private static final String REPLACE = "repalce";
	private static final String New_INSCREAN = "newIncrease";
	private static final String NEXT_SONG = "nextSong";
	private static final int REFRESH_SONG_NAME = 10000;
	
	private TextView downloadNumberTxt;
	private TextView downloadTipTxt;
	private TextView downloadProgressTxt;
	private TextView downloadingSongName;
	
	private ProgressBar downloadProgressBar;
	private ProgressBar rotateBar;
	
	private Button pauseBtn;
	
	private ArrayList<Integer> downloadSongsId;
	private int downloadnumbers;
	private int currentDownload =0;
	
	private InternetAddSongUtil instance = null;
	private UDiskAddSongUtil uDiskAddSongUtil = null;
	private FtpUnit ftpUnit = null;
	private DatabaseEncryptionUtil encryptionUtil = null;
	
	private String myChiose = "";
	private boolean checkBoxIsChecked = false;
	private boolean bool = true;
	
	private Song mSong;
	private String ftpSrc;
	private String localFileName;
	
	 public String username;
     public String pwd;
     public String ftpServer;
     public String downFileParentdir;
     public String downFileName;
     

	private Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
				if(currentDownload < downloadnumbers){
					int downloadSongId = downloadSongsId.get(currentDownload);
					mSong = instance.getDownloadSongInfo(downloadSongId);
					mainUIHandler.sendEmptyMessage(REFRESH_SONG_NAME);
					String songMvName =mSong.number + "." + mSong.format;
					ftpSrc = LeXiangConstants.SERVER_PATH + songMvName;
					boolean isSongExist = uDiskAddSongUtil.retrievalSongInfo(mSong);
					Log.d(TAG, "[handleMessage]....isSongExist===>" + isSongExist);
					if(isSongExist){
						if (myChiose != null && !"".equals(myChiose)) {
							if (NEXT_SONG.equals(myChiose)) {
								currentDownload++;
								handler.sendEmptyMessage(0);
							}else {
								new DownloadTask().execute(myChiose);
							}
						} else {
							isExistDialog();
						}
					}else{
						new DownloadTask().execute("");
					}
				}else{
					rotateBar.setVisibility(View.GONE);
					downloadTipTxt.setText(R.string.song_download_success);
					pauseBtn.setText(R.string.sure);
					HddDataBaseVersion.setCurrentHddDataBaseVersion();
				}
		}
	};
	
	private Handler mainUIHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
				case REFRESH_SONG_NAME:
					downloadingSongName.setText(mSong.songName);
				break;
				default:
					
				break;
			}
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.internet_down_load);
		this.onNewIntent(getIntent());
		initView();
	}
	
	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		downloadSongsId = intent.getIntegerArrayListExtra(InternetAddSong.SONGS_LIST);
		Log.d(TAG, "[getDownloadSongs].........downloadSongsId.size====>" + downloadSongsId.size());
		downloadnumbers = downloadSongsId.size();
		
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		Log.d(TAG, "[onResume]........");
		if(instance == null){
			instance = InternetAddSongUtil.getInstance();
		}
		if(uDiskAddSongUtil == null){
			uDiskAddSongUtil  = UDiskAddSongUtil.getInstance(InternetDownLoad.this);
		}
		if(ftpUnit == null){
			ftpUnit = FtpUnit.getInstance();
		}
		if(encryptionUtil == null){
			encryptionUtil  = DatabaseEncryptionUtil.getInstace();
		}
		handler.sendEmptyMessage(0);
	}
	
	private void initView(){
		
		downloadNumberTxt =(TextView)findViewById(R.id.download_number);
		String downloadSongNumbetStr = getString(R.string.download_song_number) + downloadnumbers + getString(R.string.initial);
		downloadNumberTxt.setText(downloadSongNumbetStr);
		
		downloadTipTxt = (TextView)findViewById(R.id.download_tip_txt);
		downloadTipTxt.setText(R.string.are_download);
		
		downloadProgressTxt = (TextView)findViewById(R.id.download_progress_txt);
		
		downloadProgressBar = (ProgressBar)findViewById(R.id.download_progress_bar);
		downloadProgressBar.setMax(100);
		
		rotateBar = (ProgressBar)findViewById(R.id.rotate_bar);
		
		downloadingSongName = (TextView)findViewById(R.id.downloading_song_name);
		
		pauseBtn = (Button)findViewById(R.id.pause_btn);
		pauseBtn.setText(R.string.pause_download);
		pauseBtn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View view) {
				String cancleBtnName = pauseBtn.getText().toString();
				Log.d(TAG, "[initView]...cancleBtnName===>" + cancleBtnName);
				if(getString(R.string.sure).equals(cancleBtnName)){
					InternetDownLoad.this.finish();
				}else{
					topDialog();
				}
			}
		});
	}
	
	class DownloadTask extends AsyncTask<String, Integer, Boolean>{

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			Log.d(TAG, "[doInBackground]....start doInBackground");
			Log.d(TAG, "[doInBackground]....params[0]====>" + params[0]);
			mSong.number = uDiskAddSongUtil.getMaxSongNum() + 1;
			if(!"".equals(params[0])){
				if(REPLACE.equals(params[0])){
					Log.d(TAG, "doInBackground............replase first");
					mSong.number = uDiskAddSongUtil.getSongNumber(mSong);
					localFileName = LeXiangConstants.SONG_HARD_DISK_PATH + mSong.number + "temp" + "." + mSong.format;
				}else {
					Log.d(TAG, "doInBackground............new insert first");
					mSong.songName = mSong.songName + getString(R.string.new_song_add);
					localFileName = LeXiangConstants.SONG_HARD_DISK_PATH + mSong.number + "." + mSong.format;
				}
			}else{
				Log.d(TAG, "doInBackground............insert first");
				localFileName = LeXiangConstants.SONG_HARD_DISK_PATH + mSong.number + "." + mSong.format;
			}
			Log.d(TAG, "[doInBackground]....ftpSrc===>" + ftpSrc);
			Log.d(TAG, "[doInBackground].....localFileName===>" + localFileName);
			try {
				resovleSrcUrl(ftpSrc);
				FTPClient ftpClient = new FTPClient();
				FileOutputStream fos = null;
				
				ftpClient.connect(ftpServer);
				ftpClient.login(username, pwd);
				ftpClient.setControlEncoding("GBK");
				ftpClient.setBufferSize(1024);
				ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
				ftpClient.setRestartOffset(0);
				
				String remoteFileName = downFileParentdir + "/" + downFileName;
				remoteFileName = new String(remoteFileName.getBytes("GBK"), "iso-8859-1");
				Log.d(TAG, "[doInBackground].....remoteFileName===>" + remoteFileName);
				fos = new FileOutputStream(localFileName);
				long remoteFileSize = getRemoteFileSize();
				Log.d(TAG, "[doInBackground]....remoteFileSize===>" + remoteFileSize);
				
				InputStream ftpIn = ftpClient.retrieveFileStream(remoteFileName);
				
				byte[] buffer = new byte[8 * 1024];
				int readLength = 0;
				long localLength = 0;
				while ((readLength=ftpIn.read(buffer)) != -1) {
					localLength += readLength; 
					publishProgress((int)((localLength* 100) / remoteFileSize));
					fos.write(buffer,0,readLength);
					fos.flush();
				}
				if(REPLACE.equals(params[0])){
					Log.d(TAG, "doInBackground............replace");
					File file = new File(LeXiangConstants.SONG_HARD_DISK_PATH, mSong.number + "temp" + "." + mSong.format);
					file.renameTo(new File(LeXiangConstants.SONG_HARD_DISK_PATH, mSong.number + "." + mSong.format));
					uDiskAddSongUtil.updateSongInfo(mSong);
				}else{
					Log.d(TAG, "doInBackground............insert");
					uDiskAddSongUtil.insertSongInfo(mSong);
				}
				Log.d(TAG, "[DownloadTask].....localFileName===>" + localFileName);
				Process p =Runtime.getRuntime().exec("chmod 777 " + localFileName);
				if(p.waitFor() == 0){
					Log.d(TAG, "[DownloadTask].....chmod success");
				}else{
					Log.d(TAG, "[DownloadTask].....chmod fialed");
				}
				ftpIn.close();
				fos.close();
				return true;
			} catch (Exception e) {
				Log.d(TAG, "[doInBackground]......e===>" + e.toString());
				return false;
			}
		}
		
		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			Log.d(TAG, "[onProgressUpdate]...values===>" +values[0]);
			downloadProgressBar.setProgress(values[0]);
			downloadProgressTxt.setText(values[0] + "%");
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			Log.d(TAG, "[onPostExecute].....result===>" + result);
			if(result){
				if (bool) {
					currentDownload ++;
					handler.sendEmptyMessage(0);
				}else{
					InternetDownLoad.this.finish();
				}
			}else{
				tipToast(getString(R.string.download_failure));
				InternetDownLoad.this.finish();
			}
		}
		
	}
	
	protected void isExistDialog() {
		AlertDialog.Builder builder = new Builder(InternetDownLoad.this);
		builder.setIcon(android.R.drawable.ic_menu_help);
		builder.setTitle(getString(R.string.whether_to_replace));
		builder.setMultiChoiceItems(new String[] { getString(R.string.remember_my_choice) }, new boolean[] { false },
				new DialogInterface.OnMultiChoiceClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which, boolean isChecked) {
						checkBoxIsChecked = isChecked;
					}
				});
		builder.setPositiveButton(getString(R.string.repalce),
				new Dialog.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						if (checkBoxIsChecked) {
							myChiose = REPLACE;
						}
						new DownloadTask().execute(REPLACE);
						dialog.dismiss();
					}
				});

		builder.setNeutralButton(getString(R.string.new_increased),
				new Dialog.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						if(checkBoxIsChecked){
							myChiose = New_INSCREAN;
						}
						new DownloadTask().execute(New_INSCREAN);
						dialog.dismiss();
					}
				});

		builder.setNegativeButton(getString(R.string.next_singer),
				new Dialog.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						if(checkBoxIsChecked){
							myChiose = NEXT_SONG;
						}
						currentDownload++;
						handler.sendEmptyMessage(0);
						dialog.dismiss();
					}
				});
		builder.create().show();
	}
	
	private void tipToast(String tip){
		Toast.makeText(InternetDownLoad.this, tip, Toast.LENGTH_SHORT).show();
	}
	
	private void topDialog(){
		AlertDialog.Builder builder = new Builder(InternetDownLoad.this);
		builder.setIcon(android.R.drawable.ic_menu_help);
		builder.setTitle(getString(R.string.sure_stop_sownload_song));
		builder.setPositiveButton(getString(R.string.yes),
				new Dialog.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						downloadTipTxt.setText(R.string.pause_download_tip);
						pauseBtn.setEnabled(false);
						bool = false;
					}
				});
		builder.setNeutralButton(getString(R.string.no), new Dialog.OnClickListener(){

			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
			
		});
		builder.show();
	}
	
	public void resovleSrcUrl(String srcUrl) throws Exception{
            String removeFTPHeader = srcUrl.substring("ftp://".length());
            String[] spiltByAt = removeFTPHeader.split("@"); 
            String userAndPwd = spiltByAt[0];
            username = userAndPwd.split(":")[0];
            pwd = userAndPwd.split(":")[1];
            String ftpdetailPath = spiltByAt[1];
            ftpServer = ftpdetailPath.substring(0, ftpdetailPath.indexOf("/"));
            downFileParentdir = ftpdetailPath.substring(ftpdetailPath.indexOf("/")+1,ftpdetailPath.lastIndexOf("/"));
            downFileName = ftpdetailPath.substring(ftpdetailPath.lastIndexOf("/")+1);
	}
	
	public long getRemoteFileSize() {
		long remoteSize = 0;
		FTPClient ftpClient = new FTPClient();
		try {
			ftpClient.connect(ftpServer);
			ftpClient.setControlEncoding("GBK");
			ftpClient.login(username, pwd);

			String parentDirPath = downFileParentdir;
			String name = downFileName;
			FTPFile[] ftpFiles = ftpClient.listFiles(parentDirPath);
			for (int i = 0; i < ftpFiles.length; i++) {
				FTPFile mFile = ftpFiles[i];
				if (name.equals(mFile.getName())) {
					remoteSize = mFile.getSize();
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			Log.d(TAG, "[getRemoteFileSize]....e===>" + e.toString());
		} finally {
			try {
				ftpClient.disconnect();
			} catch (IOException e) {
				e.printStackTrace();
				Log.d(TAG, "[getRemoteFileSize]....e===>" + e.toString());
			}
		}
		return remoteSize;
	}
}
